<?php
/**
 * Q_Input tests
 */
class Tests_Q_Rule extends UnitTestCase {

    public $input, $data;
    
    public function setUp() {
    
        $this->data = array(
            'name'          => 'Willow',
            'full_name'     => 'Davey Chavey',
            'email'         => 'ac.mattis@venenatis.edu',
            'email2'        => 'ac.mattis@vu',
            'state'         => 'Mississippi',
            'cousin'        => 'Jeannette',
            'girlfriend'    => 'Mikayla',
            'dogemail'      => 'purus.ac.tellus@Morbinonsapien.edu',
            'country'       => 'Cedarburg',
            'letters'       => 'LA',
            'numbers'       => '23234234',
            'numbers2'      => '2323 4234',
            'empty'         => '',
			'md[mu]'        => 'multilicious',
            'md[mi]'        => '',
            'neat!'         => 0,
            'match'         => 'matchus',
            'matchme'       => 'matchus',
        );
        $this->rules = new Q_Rule_Set;
    
    }
    public function tearDown() {
    
        // nothing to tear down
    
    }
    
    public function testMessagesGetSetWithStrings() {
    
        $rule = new Mock_Q_Rule();
        $this->rules->add($rule, 'name', 'Please tell us your name');
        $this->rules->validate($this->data);
        $msgs = $this->rules->getErrors();
        $this->assertEqual($msgs['name'][0], 'Please tell us your name');
    
    }
    
    public function testMessagesGetSetWithArraysAndCorrespondCorrectly() {
    
        $rule = new Mock_Q_Rule();
        $this->rules->add($rule, array('email', 'state', 'test1', 'test2'), array('Invalid E-mail', 'Invalid State'));
        $this->rules->validate($this->data);
        $msgs = $this->rules->getErrors();
        $this->assertEqual($msgs['email'][0], 'Invalid E-mail');
        $this->assertEqual($msgs['state'][0], 'Invalid State');
        $this->assertEqual($msgs['test1'][0], 'Invalid State');
        $this->assertEqual($msgs['test2'][0], 'Invalid State');
    
    }
    
    public function testAddSetCausesNoMessages() {
    
        $this->rules->add(new Q_Rule_Set);
        $this->rules->validate($this->data);
        $this->assertEqual($this->rules->getErrors(), array());
    
    }
    
    public function testOptionsCanBeSuppliedByArray() {
    
        $rule = new Mock_Q_Rule(array('field' => 'email'));
        $this->rules->add($rule, null, 'This is the error message');
        $this->rules->validate($this->data);
        $msgs = $this->rules->getErrors();
        $this->assertEqual($msgs['email'][0], 'This is the error message');
    
    }
    
    public function testRuleSetsAddToMessages() {
    
        $rules1 = new Q_Rule_Set();
        $rules1->add(new Mock_Q_Rule(), 'email', 'Invalid E-mail');
        $rules2 = new Q_Rule_Set();
        $rules2->add(new Mock_Q_Rule(), 'state', 'Invalid State');
        $this->rules->add($rules1);
        $this->rules->add($rules2);
        $this->rules->validate($this->data);
        $msgs = $this->rules->getErrors();
        $this->assertEqual($msgs['email'][0], 'Invalid E-mail');
        $this->assertEqual($msgs['state'][0], 'Invalid State');
    
    }
    
    public function testOptionalFlagCausesNoValidationWhenEmpty() {
    
        $rule = new Mock_Q_Rule(array('optional' => true));
        $this->rules->add($rule, 'neat!', 'message');
        $this->rules->validate($this->data);
        $msgs = $this->rules->getErrors();
        $this->assertFalse(isset($msgs['neat!']));
    
    }
    
    public function testValidateSingle() {
    
        $rule = new Mock_Q_Rule(array('return' => true));
        $this->assertTrue($rule->isValid($this->data['name']));
    
    }
    
    public function testWhatHappensWhenNoMessagesSetInRuleAdd() {
    }
    
    public function testValidateSpecificFields() {
    
	$rules = new Q_Rule_Set();
	$rules->add(new Mock_Q_Rule(array('return' => false)), array('name', 'email'), 'Please do something with your name and e-mail')
	      ->add(new Mock_Q_Rule(array('return' => false)), array('girlfriend', 'address', 'neat!', 'letters'), 'Please do something with your girlfriend');
	$specfields = array('name','girlfriend','letters');
	$rules->validate($this->data, $specfields); // do spec fields
	$msgs = array_keys($rules->getErrors());
	$this->assertEqual($msgs, $specfields);
	$rules->validate($this->data); // now do all
	$msgs = array_keys($rules->getErrors());
	$this->assertEqual($msgs, array('name', 'girlfriend', 'letters', 'email', 'address', 'neat!'));
    
    }
    
    // test individual rules
    public function testAlnum() {
    
        $this->rules->add(new Q_Rule_Alnum(), 'full_name', 'whitespace');
        $this->rules->add(new Q_Rule_Alnum(array('whitespace' => true)), 'full_name', 'no-whitespace');
        $this->rules->validate($this->data);
        $msgs = $this->rules->getErrors();
        $this->assertEqual($msgs['full_name'][0], 'whitespace');
        $this->assertFalse(isset($msgs['full_name'][1]));
    
    }
    public function testAlpha() {
    
        $this->rules->add(new Q_Rule_Alpha(), 'full_name', 'whitespace');
        $this->rules->add(new Q_Rule_Alpha(array('whitespace' => true)), 'full_name', 'no-whitespace');
        $this->rules->validate($this->data);
        $msgs = $this->rules->getErrors();
        $this->assertEqual($msgs['full_name'][0], 'whitespace');
        $this->assertFalse(isset($msgs['full_name'][1]));
    
    }
    public function testDigits() {
    
        $this->rules->add(new Q_Rule_Digits(), 'numbers2', 'whitespace');
        $this->rules->add(new Q_Rule_Digits(array('whitespace' => true)), 'numbers2', 'no-whitespace');
        $this->rules->validate($this->data);
        $msgs = $this->rules->getErrors();
        $this->assertEqual($msgs['numbers2'][0], 'whitespace');
        $this->assertFalse(isset($msgs['numbers2'][1]));
    
    }
    public function testEmail() {
    
        $this->rules->add(new Q_Rule_Email(), 'email', 'invalid e-mail');
        $this->rules->add(new Q_Rule_Email(), 'email2', 'invalid e-mail');
        $this->rules->validate($this->data);
        $msgs = $this->rules->getErrors();
        $this->assertEqual($msgs['email2'][0], 'invalid e-mail');
        $this->assertFalse(isset($msgs['email'][0]));
    
    }
    public function testInArray() {
    
        $array = array('test1', 'Willow');
        $this->rules->add(new Q_Rule_InArray(array('array' => $array)), 'name', 'invalid name');
        $this->rules->add(new Q_Rule_InArray(array('array' => $array)), 'state', 'invalid state');
        $this->rules->validate($this->data);
        $msgs = $this->rules->getErrors();
        $this->assertEqual($msgs['state'][0], 'invalid state');
        $this->assertFalse(isset($msgs['name'][0]));
    
    }
    public function testLength() {
    
        $this->rules->add(new Q_Rule_Length(array('min' => 5)), 'name', 'name too short');
        $this->rules->add(new Q_Rule_Length(array('min' => 5, 'max' => 10)), 'dogemail', 'name too long or short');
        $this->rules->validate($this->data);
        $msgs = $this->rules->getErrors();
        $this->assertEqual($msgs['dogemail'][0], 'name too long or short');
        $this->assertFalse(isset($msgs['name'][0]));
    
    }
    public function testMatch() {
    
        $this->rules->add(new Q_Rule_Match(array('match' => 'matchme')), 'match', 'no match to matchme');
        $this->rules->add(new Q_Rule_Match(array('match' => 'matchme')), 'name',  'no match to name');
        $this->rules->validate($this->data);
        $msgs = $this->rules->getErrors();
        $this->assertEqual($msgs['name'][0], 'no match to name');
        $this->assertFalse(isset($msgs['match'][0]));
    
    }
    public function testRange() {
    
        // not done
    
    }
    public function testRegExp() {
    
        // not done
    
    }

}